﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Tomahawk.Runtime.Localization;
using Tomahawk.Serialization;
using Tomahawk.Serialization.SerialBoost;

namespace Tomahawk.Runtime.LoadingScreens
{
    /*[XmlInclude(typeof(UIImage))]
    [XmlInclude(typeof(UIText))]*/
    public abstract class UIControl
    {
        #region Properties
        protected bool dirtySprite = true;
        protected Rectangle ScreenRectangle;
        protected Rectangle RenderRectangle;
        protected Vector2 RenderScale;
        protected Vector2 RenderOrigin;
        protected float RenderRotation;
        #endregion

        #region Serializable Properties
        [XmlAttribute("Name")]
        public string Name = "";

        [XmlAttribute("Visible")]
        public bool Visible = true;

        protected string effectChannel = "";
        [XmlAttribute("EffectChannel")]
        public string EffectChannel { get { return effectChannel; } set { dirtySprite |= (effectChannel != value); effectChannel = value; } }

        [XmlAttribute("Left")]
        public int Left = 0;

        [XmlAttribute("Top")]
        public int Top = 0;

        [XmlAttribute("Width")]
        public int Width = 1280;

        [XmlAttribute("Height")]
        public int Height = 720;

        protected float depth = 0;
        [XmlAttribute("Depth")]
        public float Depth { get { return depth; } set { dirtySprite |= (depth != value); depth = value; } }

        [XmlAttribute("Rotation")]
        public float Rotation = 0.0f;

        [XmlAttribute("Localized")]
        public bool Localized = false;

        [XmlElement("Scale")]
        public Vector2 Scale = Vector2.One;

        [XmlElement("Origin")]
        public Vector2 Origin = Vector2.Zero;

        [XmlElement("ChildControls")]
        public SerializableList<UIControl> children = new SerializableList<UIControl>();
        #endregion

        #region Loading
        internal virtual void Load(ContentManager contentManager, LocalizationManager localizationManager)
        {
            for (int idx = 0; idx < children.Count; ++idx)
            {
                children[idx].Load(contentManager, localizationManager);
            }
        }
        internal void AddToCanvas(UICanvas canvas)
        {
            canvas.AddSprite(this);
            for (int idx = 0; idx < children.Count; ++idx)
            {
                children[idx].AddToCanvas(canvas);
            }
        }
        #endregion

        #region Localization
        internal virtual void Localize(ContentManager contentManager, LocalizationManager localizationManager)
        {
            for (int idx = 0; idx < children.Count; ++idx)
            {
                children[idx].Localize(contentManager, localizationManager);
            }
        }
        #endregion

        #region Find Controls
        internal T FindControlByName<T>(string name) where T : UIControl
        {
            if (string.Compare(this.Name, name, true) == 0)
            {
                return this as T;
            }

            for (int idx = 0; idx < children.Count; ++idx)
            {
                T control = children[idx].FindControlByName<T>(name);
                if (control != null)
                {
                    return control;
                }
            }

            return null;
        }
        #endregion

        #region Render
        internal bool PreRender(ref Rectangle parentRectangle, ref Vector2 parentScale, float parentRotation)
        {
            bool result = dirtySprite;
            dirtySprite = false;

            RenderScale = parentScale * Scale;
            RenderRotation = parentRotation + Rotation;

            float sin = (float)Math.Sin(parentRotation);
            float cos = (float)Math.Cos(parentRotation);

            Vector2 offset = Vector2.Zero;
            offset.X = Left * parentScale.X;
            offset.Y = Top * parentScale.Y;

            RenderRectangle.X = (int)Math.Round(parentRectangle.X + offset.X * cos - offset.Y * sin);
            RenderRectangle.Y = (int)Math.Round(parentRectangle.Y + offset.Y * cos + offset.X * sin);

            RenderRectangle.Width = (int)(RenderScale.X * Width);
            RenderRectangle.Height = (int)(RenderScale.Y * Height);

            RenderOrigin = Origin;

            for (int idx = 0; idx < children.Count; ++idx)
            {
                result |= children[idx].PreRender(ref RenderRectangle, ref RenderScale, RenderRotation);
            }

            return result;
        }

        internal abstract void Render(UICanvas canvas, SpriteBatch spriteBatch);
        #endregion
    }
}
